
package org.nViron.Client;

import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.media.opengl.GLAutoDrawable;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.nViron.Render.GLContext;
import java.awt.Color;
import java.awt.Dialog.ModalExclusionType;
import java.awt.Font;
import org.nViron.nvGraffiti.nvGraffitiSource;
import com.sun.opengl.util.Animator;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.DecimalFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import javax.swing.AbstractListModel;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import org.nViron.Render.RendererGL;
import org.nViron.nvTiles.TileSourceGL;
import org.nViron.nvProjection.nvMercator;
import org.nViron.nvCommon.nvPosition;
import org.nViron.nvData.nvDataSource;
import org.nViron.nvMaps.nvMapSource;
import org.nViron.nvParams.nvContextParam;
import org.nViron.nvParams.nvContextParamMgr.CONTEXTPARAM;
import org.nViron.nvParams.nvParamBinding;
import org.nViron.nvParams.nvParamTerm;
import org.nViron.nvParams.nvVizParam;
import org.nViron.nvParams.nvVizParamMgr.VIZPARAM;
import org.nViron.nvRender.nvRenderer;
import org.nViron.nvSim.nvSimulator;

/**
 * Main GUI class, does all the UI stuff and simulator/nViron instantiation
 * @author Roland Haring <p>
 * <script type="text/javascript" src="http://www.ohloh.net/p/376434/widgets/project_basic_stats.js"></script>
 */
public class Composer extends JFrame {

    static {
        // When using a GLCanvas, we have to set the Popup-Menues to be HeavyWeight,
        // so they display properly on top of the GLCanvas
        JPopupMenu.setDefaultLightWeightPopupEnabled(false);
    }
    private nvDataSource dataSource;
    private nvSimulator simulator;
    private nvMapSource mapSource;
    private Config config;
    private Animator animator;
    private boolean isFullscreen;
    private long updatestamp = System.currentTimeMillis();
    private VIZPARAM selectedVizParam = VIZPARAM.INVALID;
    private CONTEXTPARAM selectedContextParam = CONTEXTPARAM.INVALID;

    /** Creates new form MainFrame */
    public Composer() {

        setUndecorated(true);
        setVisible(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        initComponents();
        setTitle("nViron");

        Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        int width = screen.width * 3 / 4;
        int height = screen.height * 3 / 4;
        setBounds((screen.width - width) / 2, (screen.height - height) / 2, width, height);

        OpenGLCanvas.addGLEventListener(new GLContext(this));
        animator = new Animator(OpenGLCanvas);
        animator.setRunAsFastAsPossible(false);

        // This is a workaround for the GLCanvas not adjusting its size, when the frame is resized.
        OpenGLCanvas.setMinimumSize(new Dimension());

        this.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                // Run this on another thread than the AWT event queue to
                // make sure the call to Animator.stop() completes before
                // exiting
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        animator.stop();
                        System.exit(0);
                    }
                }).start();
            }
        });

        initnVirion();

        initGUI();

        setVisible(true);
        setFocusable(true);
        OpenGLCanvas.setFocusable(true);
        OpenGLCanvas.requestFocus();
    }

    private void initGUI() {
        VizParamList.setModel(new DefaultListModel());
        DefaultListModel model = (DefaultListModel) VizParamList.getModel();
        for (int i=0; i<simulator.getVizParamMgr().size(); i++) {
            nvVizParam param = (nvVizParam)simulator.getVizParamMgr().get(i);
            if (i == 0) {
                VizParamTextArea.setText(param.getDescription());
            }
            model.add(i, param.getIdentifier());
        }

        ContextParamList.setModel(new DefaultListModel());
        model = (DefaultListModel) ContextParamList.getModel();
       for (int i=0; i<simulator.getContextParamMgr().size(); i++) {
            nvContextParam param = (nvContextParam)simulator.getContextParamMgr().get(i);
            if (!simulator.getDataSourceMgr().doesProvide(param.getKind())) {
               // continue;
               // should be disabled in list but this does not work!!
            }
            if (i == 0) {
                ContextParamTextArea.setText(param.getDescription());
            }
            model.add(i, param.getIdentifier());
        }
        ruleContextParamList.setModel(new DefaultListModel());
        updateRulePanel();
    }

    @Override
    public void setVisible(boolean show) {
        if (!show && animator != null) {
            animator.stop();
        }
        super.setVisible(show);
        if (show && animator != null && !animator.isAnimating()) {
            animator.start();
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        Background = new JPanel();
        RulePanel = new JPanel();
        RulesLabel = new JLabel();
        ParametersLabel = new JLabel();
        ruleVizParamLabel = new JLabel();
        rulesContextParamPanel = new JPanel();
        jScrollPane3 = new JScrollPane();
        ruleContextParamList = new JList();
        jPanel1 = new JPanel();
        RulesLabel3 = new JLabel();
        rulesSliderContextWeight = new JSlider();
        rulesContextParamWeight = new JTextField();
        decayPanel = new JPanel();
        RulesLabel5 = new JLabel();
        rulesContextParamDecay = new JTextField();
        rulesSliderContextDecay = new JSlider();
        RulesLabel4 = new JLabel();
        jPanel3 = new JPanel();
        rulesInvertBox = new JCheckBox();
        rulesRemoveButton = new JButton();
        rulesAddButton = new JButton();
        jPanel4 = new JPanel();
        RulesLabel1 = new JLabel();
        rulesSliderVizWeight = new JSlider();
        rulesVizParamWeight = new JTextField();
        rulesVizParamOffset = new JTextField();
        rulesSliderVizOffset = new JSlider();
        RulesLabel6 = new JLabel();
        RulesLabel2 = new JLabel();
        loadButton = new JButton();
        saveButton = new JButton();
        VizParamPanel = new JPanel();
        VizParamLabel = new JLabel();
        VizParamPane = new JScrollPane();
        VizParamList = new JList();
        jScrollPane1 = new JScrollPane();
        VizParamTextArea = new JTextArea();
        ContextParamPanel = new JPanel();
        ContextParamPane = new JScrollPane();
        ContextParamList = new JList();
        ContextParamLabel = new JLabel();
        jScrollPane2 = new JScrollPane();
        ContextParamTextArea = new JTextArea();
        ControlPanel = new JPanel();
        CloseButton = new JButton();
        jTextField1 = new JTextField();
        MaxButton = new JButton();
        NoGUIButton = new JButton();
        AndroidButton = new JButton();
        openglPanel = new JPanel();
        OpenGLCanvas = new GLCanvas(createGLCapabilites());
        shoutPanel = new JPanel();
        shoutTextField = new JTextField();
        shoutButton = new JButton();
        jMainMenu = new JMenuBar();

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setTitle("nViron");
        setBackground(new Color(0, 0, 0));
        setFont(new Font("Calibri", 0, 12)); // NOI18N
        setForeground(Color.white);
        setIconImage(Toolkit.getDefaultToolkit().createImage("icons/icon.png"));
        setModalExclusionType(ModalExclusionType.TOOLKIT_EXCLUDE);
        setName("BaseFrame"); // NOI18N

        Background.setBackground(new Color(0, 0, 0));
        Background.setForeground(new Color(240, 240, 240));
        Background.setFont(new Font("Calibri", 0, 12));
        Background.setName("MappingPanel"); // NOI18N
        Background.setRequestFocusEnabled(false);
        Background.addKeyListener(new KeyAdapter() {
            public void keyReleased(KeyEvent evt) {
                BackgroundKeyReleased(evt);
            }
            public void keyTyped(KeyEvent evt) {
                BackgroundKeyTyped(evt);
            }
        });

        RulePanel.setBackground(new Color(25, 25, 25));
        RulePanel.setForeground(new Color(240, 240, 240));
        RulePanel.setFont(new Font("Calibri", 0, 12));
        RulePanel.setPreferredSize(new Dimension(2000, 220));

        RulesLabel.setBackground(new Color(0, 0, 0));
        RulesLabel.setFont(new Font("Calibri", 0, 12));
        RulesLabel.setForeground(new Color(240, 240, 240));
        RulesLabel.setText("Rules for");

        ParametersLabel.setBackground(new Color(0, 0, 0));
        ParametersLabel.setFont(new Font("Calibri", 0, 12));
        ParametersLabel.setForeground(new Color(240, 240, 240));
        ParametersLabel.setText("Viz Param");

        ruleVizParamLabel.setBackground(new Color(25, 25, 25));
        ruleVizParamLabel.setForeground(new Color(240, 240, 240));
        ruleVizParamLabel.setText("[select]");

        rulesContextParamPanel.setBackground(new Color(25, 25, 25));
        rulesContextParamPanel.setForeground(new Color(240, 240, 240));
        rulesContextParamPanel.setFont(new Font("Calibri", 0, 11));

        ruleContextParamList.setBackground(new Color(25, 25, 25));
        ruleContextParamList.setFont(new Font("Calibri", 0, 12));
        ruleContextParamList.setForeground(new Color(240, 240, 240));
        ruleContextParamList.setModel(new AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        ruleContextParamList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        ruleContextParamList.setDoubleBuffered(true);
        ruleContextParamList.setSelectionBackground(new Color(100, 100, 100));
        ruleContextParamList.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent evt) {
                ruleContextParamListValueChanged(evt);
            }
        });
        jScrollPane3.setViewportView(ruleContextParamList);
        ruleContextParamList.getAccessibleContext().setAccessibleParent(RulePanel);

        jPanel1.setBackground(new Color(50, 50, 50));

        RulesLabel3.setBackground(new Color(0, 0, 0));
        RulesLabel3.setFont(new Font("Calibri", 0, 12));
        RulesLabel3.setForeground(new Color(240, 240, 240));
        RulesLabel3.setText("Weight");

        rulesSliderContextWeight.setBackground(new Color(50, 50, 50));
        rulesSliderContextWeight.setMaximum(1000);
        rulesSliderContextWeight.setValue(100);
        rulesSliderContextWeight.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                rulesSliderContextWeightStateChanged(evt);
            }
        });

        rulesContextParamWeight.setBackground(new Color(0, 0, 0));
        rulesContextParamWeight.setEditable(false);
        rulesContextParamWeight.setFont(new Font("Calibri", 0, 11));
        rulesContextParamWeight.setForeground(new Color(240, 240, 240));
        rulesContextParamWeight.setHorizontalAlignment(JTextField.CENTER);
        rulesContextParamWeight.setText("0,0");
        rulesContextParamWeight.setBorder(new LineBorder(new Color(25, 25, 25), 1, true));
        rulesContextParamWeight.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                rulesContextParamWeightActionPerformed(evt);
            }
        });

        GroupLayout jPanel1Layout = new GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(RulesLabel3)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(rulesSliderContextWeight, GroupLayout.PREFERRED_SIZE, 90, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(rulesContextParamWeight, GroupLayout.PREFERRED_SIZE, 44, GroupLayout.PREFERRED_SIZE)
                .addContainerGap(81, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING)
                    .addComponent(rulesContextParamWeight, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(RulesLabel3)
                    .addComponent(rulesSliderContextWeight, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        decayPanel.setBackground(new Color(50, 50, 50));

        RulesLabel5.setBackground(new Color(0, 0, 0));
        RulesLabel5.setFont(new Font("Calibri", 0, 12));
        RulesLabel5.setForeground(new Color(240, 240, 240));
        RulesLabel5.setText("per second");

        rulesContextParamDecay.setBackground(new Color(0, 0, 0));
        rulesContextParamDecay.setEditable(false);
        rulesContextParamDecay.setFont(new Font("Calibri", 0, 11));
        rulesContextParamDecay.setForeground(new Color(240, 240, 240));
        rulesContextParamDecay.setHorizontalAlignment(JTextField.CENTER);
        rulesContextParamDecay.setText("0,0");
        rulesContextParamDecay.setBorder(new LineBorder(new Color(25, 25, 25), 1, true));
        rulesContextParamDecay.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                rulesContextParamDecayActionPerformed(evt);
            }
        });

        rulesSliderContextDecay.setBackground(new Color(50, 50, 50));
        rulesSliderContextDecay.setValue(0);
        rulesSliderContextDecay.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                rulesSliderContextDecayStateChanged(evt);
            }
        });

        RulesLabel4.setBackground(new Color(0, 0, 0));
        RulesLabel4.setFont(new Font("Calibri", 0, 12));
        RulesLabel4.setForeground(new Color(240, 240, 240));
        RulesLabel4.setText("Decay");

        GroupLayout decayPanelLayout = new GroupLayout(decayPanel);
        decayPanel.setLayout(decayPanelLayout);
        decayPanelLayout.setHorizontalGroup(
            decayPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(Alignment.TRAILING, decayPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(RulesLabel4)
                .addPreferredGap(ComponentPlacement.UNRELATED)
                .addGroup(decayPanelLayout.createParallelGroup(Alignment.LEADING)
                    .addComponent(rulesSliderContextDecay, GroupLayout.PREFERRED_SIZE, 90, GroupLayout.PREFERRED_SIZE)
                    .addGroup(decayPanelLayout.createSequentialGroup()
                        .addGap(97, 97, 97)
                        .addComponent(rulesContextParamDecay, GroupLayout.PREFERRED_SIZE, 44, GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(RulesLabel5, GroupLayout.PREFERRED_SIZE, 68, GroupLayout.PREFERRED_SIZE)))
                .addGap(199, 199, 199))
        );
        decayPanelLayout.setVerticalGroup(
            decayPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(Alignment.TRAILING, decayPanelLayout.createSequentialGroup()
                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(decayPanelLayout.createParallelGroup(Alignment.LEADING)
                    .addGroup(decayPanelLayout.createParallelGroup(Alignment.BASELINE)
                        .addComponent(rulesContextParamDecay, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(RulesLabel5))
                    .addComponent(rulesSliderContextDecay, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(RulesLabel4))
                .addContainerGap())
        );

        jPanel3.setBackground(new Color(50, 50, 50));

        rulesInvertBox.setBackground(new Color(50, 50, 50));
        rulesInvertBox.setForeground(new Color(240, 240, 240));
        rulesInvertBox.setText("invert context value");
        rulesInvertBox.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                rulesInvertBoxStateChanged(evt);
            }
        });

        GroupLayout jPanel3Layout = new GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(rulesInvertBox)
                .addContainerGap(145, Short.MAX_VALUE))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(rulesInvertBox)
                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        rulesRemoveButton.setBackground(new Color(25, 25, 25));
        rulesRemoveButton.setText("Remove");
        rulesRemoveButton.setEnabled(false);
        rulesRemoveButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                rulesRemoveButtonActionPerformed(evt);
            }
        });

        rulesAddButton.setBackground(new Color(25, 25, 25));
        rulesAddButton.setText("Add");
        rulesAddButton.setEnabled(false);
        rulesAddButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                rulesAddButtonActionPerformed(evt);
            }
        });

        jPanel4.setBackground(new Color(25, 25, 25));

        RulesLabel1.setBackground(new Color(0, 0, 0));
        RulesLabel1.setFont(new Font("Calibri", 0, 12));
        RulesLabel1.setForeground(new Color(240, 240, 240));
        RulesLabel1.setText("Weight");

        rulesSliderVizWeight.setBackground(new Color(25, 25, 25));
        rulesSliderVizWeight.setMaximum(1000);
        rulesSliderVizWeight.setValue(100);
        rulesSliderVizWeight.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                rulesSliderVizWeightStateChanged(evt);
            }
        });

        rulesVizParamWeight.setBackground(new Color(0, 0, 0));
        rulesVizParamWeight.setEditable(false);
        rulesVizParamWeight.setFont(new Font("Calibri", 0, 11));
        rulesVizParamWeight.setForeground(new Color(240, 240, 240));
        rulesVizParamWeight.setHorizontalAlignment(JTextField.CENTER);
        rulesVizParamWeight.setText("1,0");
        rulesVizParamWeight.setBorder(new LineBorder(new Color(25, 25, 25), 1, true));
        rulesVizParamWeight.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                rulesVizParamWeightActionPerformed(evt);
            }
        });

        rulesVizParamOffset.setBackground(new Color(0, 0, 0));
        rulesVizParamOffset.setEditable(false);
        rulesVizParamOffset.setFont(new Font("Calibri", 0, 11));
        rulesVizParamOffset.setForeground(new Color(240, 240, 240));
        rulesVizParamOffset.setHorizontalAlignment(JTextField.CENTER);
        rulesVizParamOffset.setText("0,0");
        rulesVizParamOffset.setBorder(new LineBorder(new Color(25, 25, 25), 1, true));

        rulesSliderVizOffset.setBackground(new Color(25, 25, 25));
        rulesSliderVizOffset.setValue(0);
        rulesSliderVizOffset.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                rulesSliderVizOffsetStateChanged(evt);
            }
        });

        RulesLabel6.setBackground(new Color(0, 0, 0));
        RulesLabel6.setFont(new Font("Calibri", 0, 12));
        RulesLabel6.setForeground(new Color(240, 240, 240));
        RulesLabel6.setText("Offset");

        GroupLayout jPanel4Layout = new GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(Alignment.LEADING)
            .addGroup(Alignment.TRAILING, jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel4Layout.createParallelGroup(Alignment.TRAILING)
                    .addGroup(jPanel4Layout.createSequentialGroup()
                        .addComponent(RulesLabel6)
                        .addGap(16, 16, 16)
                        .addComponent(rulesSliderVizOffset, GroupLayout.PREFERRED_SIZE, 90, GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(rulesVizParamOffset, GroupLayout.PREFERRED_SIZE, 44, GroupLayout.PREFERRED_SIZE))
                    .addGroup(jPanel4Layout.createSequentialGroup()
                        .addComponent(RulesLabel1)
                        .addGap(10, 10, 10)
                        .addComponent(rulesSliderVizWeight, GroupLayout.PREFERRED_SIZE, 90, GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(rulesVizParamWeight, GroupLayout.PREFERRED_SIZE, 44, GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(Alignment.LEADING)
            .addGroup(Alignment.TRAILING, jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING)
                    .addGroup(jPanel4Layout.createSequentialGroup()
                        .addComponent(RulesLabel1)
                        .addPreferredGap(ComponentPlacement.RELATED))
                    .addGroup(jPanel4Layout.createParallelGroup(Alignment.TRAILING)
                        .addComponent(rulesSliderVizWeight, 0, 0, Short.MAX_VALUE)
                        .addComponent(rulesVizParamWeight, Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 16, GroupLayout.PREFERRED_SIZE)))
                .addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING)
                    .addComponent(rulesSliderVizOffset, Alignment.TRAILING, 0, 0, Short.MAX_VALUE)
                    .addComponent(rulesVizParamOffset, GroupLayout.PREFERRED_SIZE, 16, GroupLayout.PREFERRED_SIZE)
                    .addComponent(RulesLabel6))
                .addContainerGap())
        );

        GroupLayout rulesContextParamPanelLayout = new GroupLayout(rulesContextParamPanel);
        rulesContextParamPanel.setLayout(rulesContextParamPanelLayout);
        rulesContextParamPanelLayout.setHorizontalGroup(
            rulesContextParamPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(rulesContextParamPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane3, GroupLayout.PREFERRED_SIZE, 227, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addGroup(rulesContextParamPanelLayout.createParallelGroup(Alignment.TRAILING, false)
                    .addComponent(decayPanel, Alignment.LEADING, 0, 274, Short.MAX_VALUE)
                    .addComponent(jPanel1, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel3, Alignment.LEADING, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(ComponentPlacement.RELATED)
                .addGroup(rulesContextParamPanelLayout.createParallelGroup(Alignment.TRAILING)
                    .addComponent(rulesAddButton, GroupLayout.DEFAULT_SIZE, 71, Short.MAX_VALUE)
                    .addComponent(rulesRemoveButton, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(jPanel4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        rulesContextParamPanelLayout.setVerticalGroup(
            rulesContextParamPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(rulesContextParamPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(rulesContextParamPanelLayout.createParallelGroup(Alignment.LEADING)
                    .addComponent(jPanel4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addGroup(rulesContextParamPanelLayout.createSequentialGroup()
                        .addGroup(rulesContextParamPanelLayout.createParallelGroup(Alignment.LEADING, false)
                            .addGroup(rulesContextParamPanelLayout.createSequentialGroup()
                                .addComponent(rulesAddButton)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(rulesRemoveButton))
                            .addGroup(rulesContextParamPanelLayout.createSequentialGroup()
                                .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, 43, GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(decayPanel, GroupLayout.PREFERRED_SIZE, 43, GroupLayout.PREFERRED_SIZE)))
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                    .addComponent(jScrollPane3, GroupLayout.PREFERRED_SIZE, 135, GroupLayout.PREFERRED_SIZE))
                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        RulesLabel2.setBackground(new Color(0, 0, 0));
        RulesLabel2.setFont(new Font("Calibri", 0, 12)); // NOI18N
        RulesLabel2.setForeground(new Color(240, 240, 240));
        RulesLabel2.setHorizontalAlignment(SwingConstants.CENTER);
        RulesLabel2.setText("Configuration");

        loadButton.setBackground(new Color(25, 25, 25));
        loadButton.setText("Load");
        loadButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                loadButtonActionPerformed(evt);
            }
        });

        saveButton.setBackground(new Color(25, 25, 25));
        saveButton.setText("Save");
        saveButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });

        GroupLayout RulePanelLayout = new GroupLayout(RulePanel);
        RulePanel.setLayout(RulePanelLayout);
        RulePanelLayout.setHorizontalGroup(
            RulePanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(RulePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(RulePanelLayout.createParallelGroup(Alignment.LEADING)
                    .addGroup(RulePanelLayout.createSequentialGroup()
                        .addComponent(rulesContextParamPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(ComponentPlacement.RELATED, 184, Short.MAX_VALUE)
                        .addGroup(RulePanelLayout.createParallelGroup(Alignment.TRAILING, false)
                            .addComponent(RulesLabel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(saveButton, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE)
                            .addComponent(loadButton, GroupLayout.PREFERRED_SIZE, 100, GroupLayout.PREFERRED_SIZE)))
                    .addGroup(RulePanelLayout.createSequentialGroup()
                        .addComponent(RulesLabel)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(ParametersLabel)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(ruleVizParamLabel, GroupLayout.PREFERRED_SIZE, 175, GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        RulePanelLayout.setVerticalGroup(
            RulePanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(RulePanelLayout.createSequentialGroup()
                .addContainerGap(17, Short.MAX_VALUE)
                .addGroup(RulePanelLayout.createParallelGroup(Alignment.LEADING)
                    .addGroup(Alignment.TRAILING, RulePanelLayout.createSequentialGroup()
                        .addGroup(RulePanelLayout.createParallelGroup(Alignment.BASELINE)
                            .addComponent(RulesLabel)
                            .addComponent(ParametersLabel)
                            .addComponent(ruleVizParamLabel))
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(rulesContextParamPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                    .addGroup(Alignment.TRAILING, RulePanelLayout.createSequentialGroup()
                        .addComponent(RulesLabel2)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(loadButton)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(saveButton)
                        .addContainerGap())))
        );

        VizParamPanel.setBackground(new Color(25, 25, 25));
        VizParamPanel.setForeground(new Color(240, 240, 240));
        VizParamPanel.setFont(new Font("Calibri", 0, 12));

        VizParamLabel.setBackground(new Color(0, 0, 0));
        VizParamLabel.setFont(new Font("Calibri", 0, 18));
        VizParamLabel.setForeground(new Color(240, 240, 240));
        VizParamLabel.setText("VizParams");

        VizParamPane.setBorder(null);

        VizParamList.setBackground(new Color(25, 25, 25));
        VizParamList.setFont(new Font("Calibri", 0, 12));
        VizParamList.setForeground(new Color(240, 240, 240));
        VizParamList.setModel(new AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        VizParamList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        VizParamList.setDoubleBuffered(true);
        VizParamList.setSelectionBackground(new Color(100, 100, 100));
        VizParamList.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent evt) {
                VizParamListValueChanged(evt);
            }
        });
        VizParamPane.setViewportView(VizParamList);

        jScrollPane1.setBackground(new Color(0, 0, 0));
        jScrollPane1.setBorder(null);
        jScrollPane1.setForeground(new Color(240, 240, 240));
        jScrollPane1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jScrollPane1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);

        VizParamTextArea.setBackground(new Color(25, 25, 25));
        VizParamTextArea.setColumns(20);
        VizParamTextArea.setFont(new Font("Calibri", 0, 12));
        VizParamTextArea.setForeground(new Color(240, 240, 240));
        VizParamTextArea.setLineWrap(true);
        VizParamTextArea.setRows(5);
        VizParamTextArea.setWrapStyleWord(true);
        jScrollPane1.setViewportView(VizParamTextArea);
        VizParamTextArea.getAccessibleContext().setAccessibleParent(VizParamPanel);

        GroupLayout VizParamPanelLayout = new GroupLayout(VizParamPanel);
        VizParamPanel.setLayout(VizParamPanelLayout);
        VizParamPanelLayout.setHorizontalGroup(
            VizParamPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(Alignment.TRAILING, VizParamPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(VizParamPanelLayout.createParallelGroup(Alignment.TRAILING)
                    .addComponent(VizParamPane, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 155, Short.MAX_VALUE)
                    .addComponent(jScrollPane1, 0, 0, Short.MAX_VALUE)
                    .addComponent(VizParamLabel, Alignment.LEADING))
                .addContainerGap())
        );
        VizParamPanelLayout.setVerticalGroup(
            VizParamPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(VizParamPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(VizParamLabel)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(VizParamPane, GroupLayout.DEFAULT_SIZE, 366, Short.MAX_VALUE)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 73, GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        ContextParamPanel.setBackground(new Color(25, 25, 25));
        ContextParamPanel.setForeground(new Color(240, 240, 240));
        ContextParamPanel.setFont(new Font("Calibri", 0, 12));

        ContextParamPane.setBorder(null);

        ContextParamList.setBackground(new Color(25, 25, 25));
        ContextParamList.setFont(new Font("Calibri", 0, 12)); // NOI18N
        ContextParamList.setForeground(new Color(240, 240, 240));
        ContextParamList.setModel(new AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        ContextParamList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        ContextParamList.setDoubleBuffered(true);
        ContextParamList.setSelectionBackground(new Color(100, 100, 100));
        ContextParamList.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent evt) {
                ContextParamListValueChanged(evt);
            }
        });
        ContextParamPane.setViewportView(ContextParamList);

        ContextParamLabel.setBackground(new Color(0, 0, 0));
        ContextParamLabel.setFont(new Font("Calibri", 0, 18));
        ContextParamLabel.setForeground(new Color(240, 240, 240));
        ContextParamLabel.setText("ContextParams");

        jScrollPane2.setBackground(new Color(0, 0, 0));
        jScrollPane2.setBorder(null);
        jScrollPane2.setForeground(new Color(240, 240, 240));
        jScrollPane2.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jScrollPane2.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);

        ContextParamTextArea.setBackground(new Color(25, 25, 25));
        ContextParamTextArea.setColumns(20);
        ContextParamTextArea.setFont(new Font("Calibri", 0, 12)); // NOI18N
        ContextParamTextArea.setForeground(new Color(240, 240, 240));
        ContextParamTextArea.setLineWrap(true);
        ContextParamTextArea.setRows(5);
        ContextParamTextArea.setWrapStyleWord(true);
        jScrollPane2.setViewportView(ContextParamTextArea);
        ContextParamTextArea.getAccessibleContext().setAccessibleParent(ContextParamPanel);

        GroupLayout ContextParamPanelLayout = new GroupLayout(ContextParamPanel);
        ContextParamPanel.setLayout(ContextParamPanelLayout);
        ContextParamPanelLayout.setHorizontalGroup(
            ContextParamPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(ContextParamPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(ContextParamPanelLayout.createParallelGroup(Alignment.LEADING)
                    .addComponent(ContextParamLabel, GroupLayout.DEFAULT_SIZE, 165, Short.MAX_VALUE)
                    .addComponent(jScrollPane2, Alignment.TRAILING, 0, 0, Short.MAX_VALUE)
                    .addComponent(ContextParamPane, GroupLayout.PREFERRED_SIZE, 165, GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        ContextParamPanelLayout.setVerticalGroup(
            ContextParamPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(ContextParamPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(ContextParamLabel)
                .addPreferredGap(ComponentPlacement.UNRELATED)
                .addComponent(ContextParamPane, GroupLayout.DEFAULT_SIZE, 362, Short.MAX_VALUE)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, 72, GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        ControlPanel.setBackground(new Color(25, 25, 25));
        ControlPanel.setForeground(new Color(240, 240, 240));

        CloseButton.setBackground(new Color(0, 0, 0));
        CloseButton.setFont(new Font("Calibri", 0, 12));
        CloseButton.setText("X");
        CloseButton.setActionCommand("Close");
        CloseButton.setBorder(null);
        CloseButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                CloseButtonActionPerformed(evt);
            }
        });

        jTextField1.setBackground(new Color(25, 25, 25));
        jTextField1.setFont(new Font("Calibri", 0, 24));
        jTextField1.setForeground(new Color(240, 240, 240));
        jTextField1.setText("nViron");
        jTextField1.setBorder(null);

        MaxButton.setBackground(new Color(0, 0, 0));
        MaxButton.setFont(new Font("Calibri", 0, 12));
        MaxButton.setText("^");
        MaxButton.setActionCommand("Close");
        MaxButton.setBorder(null);
        MaxButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                MaxButtonActionPerformed(evt);
            }
        });

        NoGUIButton.setBackground(new Color(0, 0, 0));
        NoGUIButton.setFont(new Font("Calibri", 0, 12));
        NoGUIButton.setText("<>");
        NoGUIButton.setActionCommand("Close");
        NoGUIButton.setBorder(null);
        NoGUIButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                NoGUIButtonActionPerformed(evt);
            }
        });

        AndroidButton.setBackground(new Color(0, 0, 0));
        AndroidButton.setFont(new Font("Calibri", 0, 12));
        AndroidButton.setText("A");
        AndroidButton.setActionCommand("Close");
        AndroidButton.setBorder(null);
        AndroidButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                AndroidButtonActionPerformed(evt);
            }
        });

        GroupLayout ControlPanelLayout = new GroupLayout(ControlPanel);
        ControlPanel.setLayout(ControlPanelLayout);
        ControlPanelLayout.setHorizontalGroup(
            ControlPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(ControlPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTextField1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(ComponentPlacement.RELATED, 890, Short.MAX_VALUE)
                .addComponent(AndroidButton, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(NoGUIButton, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(MaxButton, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(CloseButton, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        ControlPanelLayout.setVerticalGroup(
            ControlPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(ControlPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(ControlPanelLayout.createParallelGroup(Alignment.BASELINE)
                    .addComponent(CloseButton, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE)
                    .addComponent(jTextField1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(MaxButton, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE)
                    .addComponent(NoGUIButton, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE)
                    .addComponent(AndroidButton, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE))
                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        openglPanel.setBackground(new Color(25, 25, 25));
        openglPanel.setForeground(new Color(240, 240, 240));
        openglPanel.setMaximumSize(new Dimension(3277, 32767));
        openglPanel.setPreferredSize(new Dimension(3139, 569));

        OpenGLCanvas.setFont(new Font("Calibri", 0, 12)); // NOI18N
        OpenGLCanvas.setName("OpenGL Canvas"); // NOI18N
        OpenGLCanvas.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent evt) {
                OpenGLCanvasMouseClicked(evt);
            }
        });
        OpenGLCanvas.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseDragged(MouseEvent evt) {
                OpenGLCanvasMouseDragged(evt);
            }
        });
        OpenGLCanvas.addFocusListener(new FocusAdapter() {
            public void focusGained(FocusEvent evt) {
                OpenGLCanvasFocusGained(evt);
            }
            public void focusLost(FocusEvent evt) {
                OpenGLCanvasFocusLost(evt);
            }
        });
        OpenGLCanvas.addKeyListener(new KeyAdapter() {
            public void keyReleased(KeyEvent evt) {
                OpenGLCanvasKeyReleased(evt);
            }
        });

        shoutPanel.setBackground(new Color(25, 25, 25));

        shoutTextField.setBackground(new Color(50, 50, 50));
        shoutTextField.setFont(new Font("Calibri", 0, 11));
        shoutTextField.setForeground(new Color(240, 240, 240));
        shoutTextField.setText("What are you looking for?");
        shoutTextField.setBorder(new LineBorder(new Color(0, 0, 0), 1, true));
        shoutTextField.setMargin(new Insets(1, 1, 1, 1));
        shoutTextField.setName("Shout"); // NOI18N
        shoutTextField.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                shoutTextFieldActionPerformed(evt);
            }
        });
        shoutTextField.addFocusListener(new FocusAdapter() {
            public void focusGained(FocusEvent evt) {
                shoutTextFieldFocusGained(evt);
            }
        });

        shoutButton.setBackground(new Color(25, 25, 25));
        shoutButton.setText("Shout!");
        shoutButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                shoutButtonActionPerformed(evt);
            }
        });

        GroupLayout shoutPanelLayout = new GroupLayout(shoutPanel);
        shoutPanel.setLayout(shoutPanelLayout);
        shoutPanelLayout.setHorizontalGroup(
            shoutPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(shoutPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(shoutTextField, GroupLayout.PREFERRED_SIZE, 211, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(shoutButton, GroupLayout.PREFERRED_SIZE, 65, GroupLayout.PREFERRED_SIZE)
                .addContainerGap(459, Short.MAX_VALUE))
        );
        shoutPanelLayout.setVerticalGroup(
            shoutPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(shoutPanelLayout.createParallelGroup(Alignment.BASELINE)
                .addComponent(shoutTextField, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE)
                .addComponent(shoutButton, GroupLayout.PREFERRED_SIZE, 24, GroupLayout.PREFERRED_SIZE))
        );

        GroupLayout openglPanelLayout = new GroupLayout(openglPanel);
        openglPanel.setLayout(openglPanelLayout);
        openglPanelLayout.setHorizontalGroup(
            openglPanelLayout.createParallelGroup(Alignment.LEADING)
            .addComponent(shoutPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(OpenGLCanvas, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 751, Short.MAX_VALUE)
        );
        openglPanelLayout.setVerticalGroup(
            openglPanelLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(Alignment.TRAILING, openglPanelLayout.createSequentialGroup()
                .addComponent(OpenGLCanvas, GroupLayout.DEFAULT_SIZE, 448, Short.MAX_VALUE)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(shoutPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        GroupLayout BackgroundLayout = new GroupLayout(Background);
        Background.setLayout(BackgroundLayout);
        BackgroundLayout.setHorizontalGroup(
            BackgroundLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(BackgroundLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(BackgroundLayout.createParallelGroup(Alignment.LEADING)
                    .addComponent(RulePanel, GroupLayout.DEFAULT_SIZE, 1123, Short.MAX_VALUE)
                    .addComponent(ControlPanel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(Alignment.TRAILING, BackgroundLayout.createSequentialGroup()
                        .addComponent(VizParamPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(openglPanel, GroupLayout.DEFAULT_SIZE, 751, Short.MAX_VALUE)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(ContextParamPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        BackgroundLayout.setVerticalGroup(
            BackgroundLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(BackgroundLayout.createSequentialGroup()
                .addComponent(ControlPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addGroup(BackgroundLayout.createParallelGroup(Alignment.LEADING)
                    .addComponent(openglPanel, GroupLayout.DEFAULT_SIZE, 496, Short.MAX_VALUE)
                    .addComponent(ContextParamPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(VizParamPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(RulePanel, GroupLayout.PREFERRED_SIZE, 196, GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        jMainMenu.setBorder(null);
        jMainMenu.setDoubleBuffered(true);
        jMainMenu.setFont(new Font("Calibri", 0, 12));
        jMainMenu.setName("Main Menu"); // NOI18N
        setJMenuBar(jMainMenu);

        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(Alignment.LEADING)
            .addComponent(Background, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(Alignment.LEADING)
            .addComponent(Background, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void CloseButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_CloseButtonActionPerformed
        animator.stop();
        dispose();
        System.exit(0);
    }//GEN-LAST:event_CloseButtonActionPerformed

    private void MaxButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_MaxButtonActionPerformed
        setFullscreen(!isFullscreen);
    }//GEN-LAST:event_MaxButtonActionPerformed

    private void NoGUIButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_NoGUIButtonActionPerformed
        if (VizParamPanel.isVisible()) {
            VizParamPanel.setVisible(false);
            ContextParamPanel.setVisible(false);
            RulePanel.setVisible(false);
        } else {
            VizParamPanel.setVisible(true);
            ContextParamPanel.setVisible(true);
            RulePanel.setVisible(true);
        }
        OpenGLCanvas.requestFocus();
        // TODO adjust exact size of opengl canvas when resizing it
    }//GEN-LAST:event_NoGUIButtonActionPerformed

    private void VizParamListValueChanged(ListSelectionEvent evt) {//GEN-FIRST:event_VizParamListValueChanged
        // When the user release the mouse button and completes the selection,
        // getValueIsAdjusting() becomes false
        if (!evt.getValueIsAdjusting()) {
            JList list = (JList) evt.getSource();
            nvVizParam vizParam = simulator.getVizParamMgr().getParam(list.getSelectedIndex());
            selectedVizParam = vizParam.getKind();
            VizParamTextArea.setText(vizParam.getDescription());
            updateRulePanel();
        }
    }//GEN-LAST:event_VizParamListValueChanged

    private void ContextParamListValueChanged(ListSelectionEvent evt) {//GEN-FIRST:event_ContextParamListValueChanged
        // When the user release the mouse button and completes the selection,
        // getValueIsAdjusting() becomes false
        if (!evt.getValueIsAdjusting()) {
            JList list = (JList) evt.getSource();
            nvContextParam contextParam = simulator.getContextParamMgr().getParam(list.getSelectedIndex());
            ContextParamTextArea.setText(contextParam.getDescription());
            selectedContextParam = contextParam.getKind();
            updateRulePanel();
            // update add button
            nvParamBinding binding = simulator.getParamBindingMgr().getParamBinding(selectedVizParam);
            rulesAddButton.setEnabled(binding != null && !binding.usesContextParam(selectedContextParam));
        }
    }//GEN-LAST:event_ContextParamListValueChanged

    private void OpenGLCanvasMouseClicked(MouseEvent evt) {//GEN-FIRST:event_OpenGLCanvasMouseClicked
        OpenGLCanvas.setFocusable(true);
        OpenGLCanvas.requestFocus();
    }//GEN-LAST:event_OpenGLCanvasMouseClicked

    private void OpenGLCanvasKeyReleased(KeyEvent evt) {//GEN-FIRST:event_OpenGLCanvasKeyReleased
        float deltaPos = 0.0005f;
        float deltaAlt = 50.0f;
        boolean shiftDown = (evt.getModifiersEx() & KeyEvent.SHIFT_DOWN_MASK) == KeyEvent.SHIFT_DOWN_MASK;
        boolean ctrlDown = (evt.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) == KeyEvent.CTRL_DOWN_MASK;

        nvPosition posC = simulator.getCameraPosition();
        nvPosition posL = simulator.getLookAtPosition();

        switch (evt.getKeyCode()) {
            case KeyEvent.VK_G:
                simulator.getRenderer().setRenderGrid(!simulator.getRenderer().isRenderGrid());
                break;
            case KeyEvent.VK_B:
                simulator.getRenderer().setRenderDebugInfo(!simulator.getRenderer().isRenderDebugInfo());
                break;
            case KeyEvent.VK_I:
                simulator.getRenderer().setRenderInfo(!simulator.getRenderer().isRenderInfo());
                break;
            case KeyEvent.VK_A:
                if (!shiftDown) {
                    posC.setLongitude(posC.getLongitude() - deltaPos);
                }
                if (!ctrlDown) {
                    posL.setLongitude(posL.getLongitude() - deltaPos);
                }
                break;
            case KeyEvent.VK_D:
                if (!shiftDown) {
                    posC.setLongitude(posC.getLongitude() + deltaPos);
                }
                if (!ctrlDown) {
                    posL.setLongitude(posL.getLongitude() + deltaPos);
                }
                break;
            case KeyEvent.VK_W:
                if (!shiftDown) {
                    posC.setLatitude(posC.getLatitude() + deltaPos);
                }
                if (!ctrlDown) {
                    posL.setLatitude(posL.getLatitude() + deltaPos);
                }
                break;
            case KeyEvent.VK_S:
                if (!shiftDown) {
                    posC.setLatitude(posC.getLatitude() - deltaPos);
                }
                if (!ctrlDown) {
                    posL.setLatitude(posL.getLatitude() - deltaPos);
                }
                break;
            case KeyEvent.VK_PAGE_UP:
                if (!shiftDown) {
                    posC.setAltitude(posC.getAltitude() + deltaAlt);
                }
                if (!ctrlDown) {
                    posL.setAltitude(posL.getAltitude() + deltaAlt);
                }
                break;
            case KeyEvent.VK_PAGE_DOWN:
                if (!shiftDown) {
                    posC.setAltitude(posC.getAltitude() - deltaAlt);
                }
                if (!ctrlDown) {
                    posL.setAltitude(posL.getAltitude() - deltaAlt);
                }
                break;
            case KeyEvent.VK_LEFT:
                simulator.rotCamera(-10.0f);
                break;
            case KeyEvent.VK_RIGHT:
                simulator.rotCamera(10.0f);
                break;
            case KeyEvent.VK_UP:
                simulator.movCamera(40.0f);
                break;
            case KeyEvent.VK_DOWN:
                simulator.movCamera(-20.0f);
                break;
        }
    }//GEN-LAST:event_OpenGLCanvasKeyReleased

    private void BackgroundKeyTyped(KeyEvent evt) {//GEN-FIRST:event_BackgroundKeyTyped
    }//GEN-LAST:event_BackgroundKeyTyped

    private void BackgroundKeyReleased(KeyEvent evt) {//GEN-FIRST:event_BackgroundKeyReleased
    }//GEN-LAST:event_BackgroundKeyReleased

    private void OpenGLCanvasFocusGained(FocusEvent evt) {//GEN-FIRST:event_OpenGLCanvasFocusGained
    }//GEN-LAST:event_OpenGLCanvasFocusGained

    private void OpenGLCanvasFocusLost(FocusEvent evt) {//GEN-FIRST:event_OpenGLCanvasFocusLost
    }//GEN-LAST:event_OpenGLCanvasFocusLost

    private void shoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_shoutButtonActionPerformed
        simulator.setSearchString(shoutTextField.getText());
    }//GEN-LAST:event_shoutButtonActionPerformed

    private void shoutTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_shoutTextFieldActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_shoutTextFieldActionPerformed

    private void rulesVizParamWeightActionPerformed(ActionEvent evt) {//GEN-FIRST:event_rulesVizParamWeightActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_rulesVizParamWeightActionPerformed

    private void rulesContextParamWeightActionPerformed(ActionEvent evt) {//GEN-FIRST:event_rulesContextParamWeightActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_rulesContextParamWeightActionPerformed

    private void rulesContextParamDecayActionPerformed(ActionEvent evt) {//GEN-FIRST:event_rulesContextParamDecayActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_rulesContextParamDecayActionPerformed

    private void AndroidButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_AndroidButtonActionPerformed
        if (VizParamPanel.isVisible()) {
            VizParamPanel.setVisible(false);
            ContextParamPanel.setVisible(false);
            RulePanel.setVisible(false);
            NoGUIButton.setVisible(false);
            MaxButton.setVisible(false);
            Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
            int width = 320;
            int height = 480;
            setBounds((screen.width - width) / 2, (screen.height - height) / 2, width, height);
        } else {
            VizParamPanel.setVisible(true);
            ContextParamPanel.setVisible(true);
            RulePanel.setVisible(true);
            NoGUIButton.setVisible(true);
            MaxButton.setVisible(true);
            Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
            int width = screen.width * 3 / 4;
            int height = screen.height * 3 / 4;
            setBounds((screen.width - width) / 2, (screen.height - height) / 2, width, height);
        }
        OpenGLCanvas.requestFocus();
    }//GEN-LAST:event_AndroidButtonActionPerformed

    private void ruleContextParamListValueChanged(ListSelectionEvent evt) {//GEN-FIRST:event_ruleContextParamListValueChanged
         // When the user release the mouse button and completes the selection,
        // getValueIsAdjusting() becomes false
        if (!evt.getValueIsAdjusting()) {
            JList list = (JList) evt.getSource();
            updateRuleTerm(list.getSelectedIndex());
        }
    }//GEN-LAST:event_ruleContextParamListValueChanged

    private void rulesSliderContextWeightStateChanged(ChangeEvent evt) {//GEN-FIRST:event_rulesSliderContextWeightStateChanged
        float newVal = (float)((JSlider)evt.getSource()).getValue() / 100.0f;
        rulesContextParamWeight.setText(new DecimalFormat("0.00##").format((double)newVal));
        nvParamBinding binding = simulator.getParamBindingMgr().getParamBinding(selectedVizParam);
        int index = ruleContextParamList.getSelectedIndex();
        if (binding != null && index >= 0) {
            binding.getTerm(index).setWeight(newVal);
        }
    }//GEN-LAST:event_rulesSliderContextWeightStateChanged

    private void rulesSliderContextDecayStateChanged(ChangeEvent evt) {//GEN-FIRST:event_rulesSliderContextDecayStateChanged
        float newVal = (float)((JSlider)evt.getSource()).getValue() / 100.0f;
        rulesContextParamDecay.setText(new DecimalFormat("0.00##").format((double)newVal));
        nvParamBinding binding = simulator.getParamBindingMgr().getParamBinding(selectedVizParam);
        int index = ruleContextParamList.getSelectedIndex();
        if (binding != null && index >= 0) {
            binding.getTerm(index).setDecay(newVal);
        }
    }//GEN-LAST:event_rulesSliderContextDecayStateChanged

    private void rulesSliderVizWeightStateChanged(ChangeEvent evt) {//GEN-FIRST:event_rulesSliderVizWeightStateChanged
        nvParamBinding binding = simulator.getParamBindingMgr().getParamBinding(selectedVizParam);
        if (binding != null) {
            float newVal = (float)((JSlider)evt.getSource()).getValue() / 100.0f;
            binding.setWeight(newVal);
            rulesVizParamWeight.setText(new DecimalFormat("0.00##").format((double)newVal));
        }
    }//GEN-LAST:event_rulesSliderVizWeightStateChanged

    private void rulesInvertBoxStateChanged(ChangeEvent evt) {//GEN-FIRST:event_rulesInvertBoxStateChanged
       // TODO add your handling code here:
    }//GEN-LAST:event_rulesInvertBoxStateChanged

    private void rulesAddButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_rulesAddButtonActionPerformed
        nvParamBinding binding = simulator.getParamBindingMgr().getParamBinding(selectedVizParam);
        if (binding != null && selectedContextParam != CONTEXTPARAM.INVALID) {
            float weight = (float)rulesSliderContextWeight.getValue() / 100.0f;
            float decay = (float)rulesSliderContextDecay.getValue() / 100.0f;
            binding.addTerm(selectedContextParam, weight, decay, rulesInvertBox.isSelected());
            updateRulePanel();
        }
    }//GEN-LAST:event_rulesAddButtonActionPerformed

    private void rulesRemoveButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_rulesRemoveButtonActionPerformed
        nvParamBinding binding = simulator.getParamBindingMgr().getParamBinding(selectedVizParam);
        int index = ruleContextParamList.getSelectedIndex();
        if (binding != null && index >= 0) {
            binding.removeTerm(index);
            updateRulePanel();
        }
    }//GEN-LAST:event_rulesRemoveButtonActionPerformed

    private void OpenGLCanvasMouseDragged(MouseEvent evt) {//GEN-FIRST:event_OpenGLCanvasMouseDragged
        // TODO add your handling code here:
    }//GEN-LAST:event_OpenGLCanvasMouseDragged

    private void shoutTextFieldFocusGained(FocusEvent evt) {//GEN-FIRST:event_shoutTextFieldFocusGained
        shoutTextField.setText("");
    }//GEN-LAST:event_shoutTextFieldFocusGained

    private void rulesSliderVizOffsetStateChanged(ChangeEvent evt) {//GEN-FIRST:event_rulesSliderVizOffsetStateChanged
        nvParamBinding binding = simulator.getParamBindingMgr().getParamBinding(selectedVizParam);
        if (binding != null) {
            float newVal = (float)((JSlider)evt.getSource()).getValue() / 100.0f;
            binding.setOffset(newVal);
            rulesVizParamOffset.setText(new DecimalFormat("0.00##").format((double)newVal));
        }
    }//GEN-LAST:event_rulesSliderVizOffsetStateChanged

    private void loadButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_loadButtonActionPerformed
        simulator.loadParams();
    }//GEN-LAST:event_loadButtonActionPerformed

    private void saveButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
        simulator.saveParams();
    }//GEN-LAST:event_saveButtonActionPerformed

    /**
     * Called from within initComponents().
     * hint: to customize the generated code choose 'Customize Code' in the contextmenu
     * of the selected UI Component you wish to cutomize in design mode.
     * @return Returns customized GLCapabilities.
     */
    private GLCapabilities createGLCapabilites() {

        GLCapabilities capabilities = new GLCapabilities();
        capabilities.setHardwareAccelerated(true);
        capabilities.setDoubleBuffered(true);

        // try to enable 2x anti aliasing - should be supported on most hardware
        capabilities.setNumSamples(2);
        capabilities.setSampleBuffers(true);

        capabilities.setStencilBits(2);

        return capabilities;
    }

    private void initnVirion() {

        config = new Config();
        config.loadConfig("/data/config.xml");

        simulator = nvSimulator.getInstance();
        simulator.init(config, new nvMercator());

        dataSource = new nvGraffitiSource(simulator.getDataSourceMgr());
        mapSource = new TileSourceGL(simulator, (nvGraffitiSource)dataSource);
        if (!mapSource.init()) {
            Debug.out.println("Failed to init Mapclient!");
        }
        simulator.addMapSource(mapSource);

        if (!dataSource.init()) {
            Debug.out.println("Failed to init Baseclient");
        }
        simulator.addDataSource(dataSource);

        nvParamBinding binding = new nvParamBinding(VIZPARAM.BIODIVERSITY_L1);
        binding.addTerm(CONTEXTPARAM.CREATOR, 1.0f, 0.0f, false);
        simulator.getParamBindingMgr().addParamBinding(binding);
        binding = new nvParamBinding(VIZPARAM.BIODIVERSITY_L2);
        binding.addTerm(CONTEXTPARAM.ADDRESSE_FRIEND, 1.0f, 0.0f, false);
        simulator.getParamBindingMgr().addParamBinding(binding);
        binding = new nvParamBinding(VIZPARAM.BIODIVERSITY_L3);
        binding.addTerm(CONTEXTPARAM.POPULARITY, 1.0f, 0.0f, false);
        simulator.getParamBindingMgr().addParamBinding(binding);
        binding = new nvParamBinding(VIZPARAM.METABOLISM);
        binding.addTerm(CONTEXTPARAM.ADDRESSE, 1.0f, 0.0f, false);
        simulator.getParamBindingMgr().addParamBinding(binding);
        binding = new nvParamBinding(VIZPARAM.APPERANCE_COLOR_R);
        binding.addTerm(CONTEXTPARAM.ALERT, 1.0f, 0.0f, false);
        simulator.getParamBindingMgr().addParamBinding(binding);
        binding = new nvParamBinding(VIZPARAM.APPERANCE_COLOR_G);
        binding.addTerm(CONTEXTPARAM.CATEGORIES_SELECTED, 1.0f, 0.0f, false);
        simulator.getParamBindingMgr().addParamBinding(binding);
        binding = new nvParamBinding(VIZPARAM.APPERANCE_COLOR_B);
        binding.addTerm(CONTEXTPARAM.MIME_TYPE, 1.0f, 0.0f, false);
        simulator.getParamBindingMgr().addParamBinding(binding);
    }

    private void setFullscreen(boolean val) {
        isFullscreen = val;
        if (isFullscreen) {
            setExtendedState(MAXIMIZED_BOTH);
        } else {
            setExtendedState(NORMAL);
        }
        OpenGLCanvas.requestFocus();
    }

    public void onDisplay(GLAutoDrawable drawable) {
        if (simulator.getRenderer() == null) {
            nvRenderer renderer = new RendererGL(drawable, simulator);
            renderer.init();
            ((TileSourceGL) mapSource).setRenderer((RendererGL) renderer);
            simulator.setRenderer(renderer);
        }

        long diff = System.currentTimeMillis() - updatestamp;
        updatestamp += diff;
        int brake = 1000/30-(int)diff;
        if (brake > 0) {
            try {
                Thread.sleep(brake);
                updatestamp += brake;
                diff += brake;
            } catch (InterruptedException ex) {
                Logger.getLogger(Composer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        float deltaT = (float)diff / 1000.0f;
        simulator.update(deltaT);
        simulator.render();
    }

    public void onReshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
        if (simulator.getRenderer() == null) {
            nvRenderer renderer = new RendererGL(drawable, simulator);
            renderer.init();
            ((TileSourceGL) mapSource).setRenderer((RendererGL) renderer);
            simulator.setRenderer(renderer);
        }

        simulator.getRenderer().onReshape(x, y, width, height);
    }

    public void onDisplayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
        if (simulator.getRenderer() == null) {
            nvRenderer renderer = new RendererGL(drawable, simulator);
            renderer.init();
            ((TileSourceGL) mapSource).setRenderer((RendererGL) renderer);
            simulator.setRenderer(renderer);
        } else {
            ((RendererGL)simulator.getRenderer()).setDrawable(drawable);
        }

        ((TileSourceGL) mapSource).setRenderer((RendererGL)simulator.getRenderer());
    }

    private void updateRulePanel() {
        nvVizParam vizParam = simulator.getVizParamMgr().getParam(selectedVizParam);
        nvParamBinding binding = null;
        if (vizParam != null) {
            ruleVizParamLabel.setText(vizParam.getIdentifier());
            binding = simulator.getParamBindingMgr().getParamBinding(selectedVizParam);
            if (binding != null) {
                rulesVizParamWeight.setText(new DecimalFormat("0.00##").format((double)binding.getWeight()));
                rulesSliderVizWeight.setValue((int)(binding.getWeight()*100));
                rulesSliderVizWeight.setEnabled(true);
                rulesVizParamOffset.setText(new DecimalFormat("0.00##").format((double)binding.getOffset()));
                rulesSliderVizOffset.setValue((int)(binding.getOffset()*100));
                rulesSliderVizOffset.setEnabled(true);
            }
        } else {
            ruleVizParamLabel.setText("[select]");
        }
        if (binding == null) {
            rulesVizParamWeight.setText("1,00");
            rulesSliderVizWeight.setValue(100);
            rulesSliderVizWeight.setEnabled(false);
            rulesVizParamOffset.setText("0,00");
            rulesSliderVizOffset.setValue(0);
            rulesSliderVizOffset.setEnabled(false);
        }
        updateRuleContextParamList();
    }
    
    private void updateRuleContextParamList() {
        DefaultListModel model = (DefaultListModel)ruleContextParamList.getModel();
        model.clear();
        nvParamBinding binding = simulator.getParamBindingMgr().getParamBinding(selectedVizParam);
        if (binding != null && binding.size() > 0) {
            // add terms
            for (int i=0; i<binding.size(); i++) {
                nvParamTerm term = (nvParamTerm)binding.getTerm(i);
                nvContextParam param = simulator.getContextParamMgr().getParam(term.getParam());
                model.add(i, param.getIdentifier());
            }
            ruleContextParamList.setSelectedIndex(0);
            updateRuleTerm(0);
        } else {
            updateRuleTerm(-1);
        }
    }

    private void updateRuleTerm(int index) {
        if (index == -1) {
            rulesSliderContextDecay.setValue(0);
            rulesSliderContextDecay.setEnabled(false);
            rulesSliderContextWeight.setValue(100);
            rulesSliderContextWeight.setEnabled(false);
            rulesContextParamDecay.setText("0,00");
            rulesContextParamWeight.setText("1,00");
            rulesInvertBox.setEnabled(false);
            rulesAddButton.setEnabled(false);
            rulesRemoveButton.setEnabled(false);
        }  else {
            nvParamBinding binding = simulator.getParamBindingMgr().getParamBinding(selectedVizParam);
            nvParamTerm term = (nvParamTerm)binding.getTerm(index);
            rulesSliderContextDecay.setValue((int)(term.getDecay()*100));
            rulesSliderContextDecay.setEnabled(true);
            rulesSliderContextWeight.setValue((int)(term.getWeight()*100));
            rulesSliderContextWeight.setEnabled(true);
            rulesContextParamDecay.setText(new DecimalFormat("0.00##").format((double)term.getDecay()));
            rulesContextParamWeight.setText(new DecimalFormat("0.00##").format((double)term.getWeight()));
            rulesInvertBox.setEnabled(true);
            rulesInvertBox.setSelected(term.isInverted());
            rulesAddButton.setEnabled(!binding.usesContextParam(selectedContextParam) && selectedContextParam != CONTEXTPARAM.INVALID);
            rulesRemoveButton.setEnabled(true);
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        // Run this in the AWT event thread to prevent deadlocks and race conditions
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {

                // switch to system l&f for native font rendering etc.
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                    Logger.getLogger(getClass().getName()).log(Level.INFO, "can not enable system look and feel", ex);
                }

                Composer frame = new Composer();
                frame.setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private JButton AndroidButton;
    private JPanel Background;
    private JButton CloseButton;
    private JLabel ContextParamLabel;
    private JList ContextParamList;
    private JScrollPane ContextParamPane;
    private JPanel ContextParamPanel;
    private JTextArea ContextParamTextArea;
    private JPanel ControlPanel;
    private JButton MaxButton;
    private JButton NoGUIButton;
    private GLCanvas OpenGLCanvas;
    private JLabel ParametersLabel;
    private JPanel RulePanel;
    private JLabel RulesLabel;
    private JLabel RulesLabel1;
    private JLabel RulesLabel2;
    private JLabel RulesLabel3;
    private JLabel RulesLabel4;
    private JLabel RulesLabel5;
    private JLabel RulesLabel6;
    private JLabel VizParamLabel;
    private JList VizParamList;
    private JScrollPane VizParamPane;
    private JPanel VizParamPanel;
    private JTextArea VizParamTextArea;
    private JPanel decayPanel;
    private JMenuBar jMainMenu;
    private JPanel jPanel1;
    private JPanel jPanel3;
    private JPanel jPanel4;
    private JScrollPane jScrollPane1;
    private JScrollPane jScrollPane2;
    private JScrollPane jScrollPane3;
    private JTextField jTextField1;
    private JButton loadButton;
    private JPanel openglPanel;
    private JList ruleContextParamList;
    private JLabel ruleVizParamLabel;
    private JButton rulesAddButton;
    private JTextField rulesContextParamDecay;
    private JPanel rulesContextParamPanel;
    private JTextField rulesContextParamWeight;
    private JCheckBox rulesInvertBox;
    private JButton rulesRemoveButton;
    private JSlider rulesSliderContextDecay;
    private JSlider rulesSliderContextWeight;
    private JSlider rulesSliderVizOffset;
    private JSlider rulesSliderVizWeight;
    private JTextField rulesVizParamOffset;
    private JTextField rulesVizParamWeight;
    private JButton saveButton;
    private JButton shoutButton;
    private JPanel shoutPanel;
    private JTextField shoutTextField;
    // End of variables declaration//GEN-END:variables

}
